home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / galivan.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  11KB  |  426 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. d800-dbff    foreground:            char low bits (1 screen * 1024 chars/screen)
  8. dc00-dfff    foreground attribute:    7        ?
  9.                          6543        color
  10.                              21    ?
  11.                                0    char hi bit
  12.  
  13.  
  14. e000-e0ff    spriteram:  64 sprites (4 bytes/sprite)
  15.         offset :    0        1        2        3
  16.         meaning:    ypos(lo)    sprite(lo)    attribute    xpos(lo)
  17.                                 7   flipy
  18.                                 6   flipx
  19.                                 5-2 color
  20.                                 1   sprite(hi)
  21.                                 0   xpos(hi)
  22.  
  23.  
  24. background:    0x4000 bytes of ROM:    76543210    tile code low bits
  25.         0x4000 bytes of ROM:    7        ?
  26.                          6543        color
  27.                              2    ?
  28.                               10    tile code high bits
  29.  
  30. ***************************************************************************/
  31.  
  32. #include "driver.h"
  33. #include "vidhrdw/generic.h"
  34.  
  35. static unsigned char scrollx[2], scrolly[2];
  36.  
  37. /* Layers has only bits 5-6 active.
  38.    6 selects background off/on
  39.    5 is unknown (active only on title screen,
  40.      not for scores or push start nor game)
  41. */
  42.  
  43. static int flipscreen, layers;
  44.  
  45. static struct tilemap *bg_tilemap, *tx_tilemap;
  46.  
  47. static const unsigned char *spritepalettebank;
  48. static int ninjemak_dispdisable;
  49.  
  50.  
  51.  
  52. /***************************************************************************
  53.  
  54.   Convert the color PROMs into a more useable format.
  55.  
  56. ***************************************************************************/
  57.  
  58. void galivan_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  59. {
  60.     int i;
  61.     #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
  62.     #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
  63.  
  64.     for (i = 0;i < Machine->drv->total_colors;i++)
  65.     {
  66.         int bit0,bit1,bit2,bit3;
  67.  
  68.         bit0 = (color_prom[0] >> 0) & 0x01;
  69.         bit1 = (color_prom[0] >> 1) & 0x01;
  70.         bit2 = (color_prom[0] >> 2) & 0x01;
  71.         bit3 = (color_prom[0] >> 3) & 0x01;
  72.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  73.         bit0 = (color_prom[Machine->drv->total_colors] >> 0) & 0x01;
  74.         bit1 = (color_prom[Machine->drv->total_colors] >> 1) & 0x01;
  75.         bit2 = (color_prom[Machine->drv->total_colors] >> 2) & 0x01;
  76.         bit3 = (color_prom[Machine->drv->total_colors] >> 3) & 0x01;
  77.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  78.         bit0 = (color_prom[2*Machine->drv->total_colors] >> 0) & 0x01;
  79.         bit1 = (color_prom[2*Machine->drv->total_colors] >> 1) & 0x01;
  80.         bit2 = (color_prom[2*Machine->drv->total_colors] >> 2) & 0x01;
  81.         bit3 = (color_prom[2*Machine->drv->total_colors] >> 3) & 0x01;
  82.         *(palette++) = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
  83.  
  84.         color_prom++;
  85.     }
  86.  
  87.     color_prom += 2*Machine->drv->total_colors;
  88.     /* color_prom now points to the beginning of the lookup tables */
  89.  
  90.  
  91.     /* characters use colors 0-127 */
  92.     for (i = 0;i < TOTAL_COLORS(0);i++)
  93.         COLOR(0,i) = i;
  94.  
  95.     /* I think that */
  96.     /* background tiles use colors 192-255 in four banks */
  97.     /* the bottom two bits of the color code select the palette bank for */
  98.     /* pens 0-7; the top two bits for pens 8-15. */
  99.     for (i = 0;i < TOTAL_COLORS(1);i++)
  100.     {
  101.         if (i & 8) COLOR(1,i) = 192 + (i & 0x0f) + ((i & 0xc0) >> 2);
  102.         else COLOR(1,i) = 192 + (i & 0x0f) + ((i & 0x30) >> 0);
  103.     }
  104.  
  105.  
  106.     /* sprites use colors 128-191 in four banks */
  107.     /* The lookup table tells which colors to pick from the selected bank */
  108.     /* the bank is selected by another PROM and depends on the top 7 bits of */
  109.     /* the sprite code. The PROM selects the bank *separately* for pens 0-7 and */
  110.     /* 8-15 (like for tiles). */
  111.     for (i = 0;i < TOTAL_COLORS(2)/16;i++)
  112.     {
  113.         int j;
  114.  
  115.         for (j = 0;j < 16;j++)
  116.         {
  117.             if (i & 8)
  118.                 COLOR(2,i + j * (TOTAL_COLORS(2)/16)) = 128 + ((j & 0x0c) << 2) + (*color_prom & 0x0f);
  119.             else
  120.                 COLOR(2,i + j * (TOTAL_COLORS(2)/16)) = 128 + ((j & 0x03) << 4) + (*color_prom & 0x0f);
  121.         }
  122.  
  123.         color_prom++;
  124.     }
  125.  
  126.     /* color_prom now points to the beginning of the sprite palette bank table */
  127.     spritepalettebank = color_prom;    /* we'll need it at run time */
  128. }
  129.  
  130.  
  131.  
  132. /***************************************************************************
  133.  
  134.   Callbacks for the TileMap code
  135.  
  136. ***************************************************************************/
  137.  
  138. static void get_bg_tile_info(int tile_index)
  139. {
  140.     unsigned char *BGROM = memory_region(REGION_GFX4);
  141.     int attr = BGROM[tile_index + 0x4000];
  142.     int code = BGROM[tile_index] | ((attr & 0x03) << 8);
  143.     SET_TILE_INFO(1,code,(attr & 0x78) >> 3);    /* seems correct */
  144. }
  145.  
  146. static void get_tx_tile_info(int tile_index)
  147. {
  148.     int attr = colorram[tile_index];
  149.     int code = videoram[tile_index] | ((attr & 0x01) << 8);
  150.     SET_TILE_INFO(0,code,(attr & 0xe0) >> 5);    /* not sure */
  151.     tile_info.priority = attr & 8 ? 0 : 1;    /* wrong */
  152. }
  153.  
  154. static void ninjemak_get_bg_tile_info(int tile_index)
  155. {
  156.     unsigned char *BGROM = memory_region(REGION_GFX4);
  157.     int attr = BGROM[tile_index + 0x4000];
  158.     int code = BGROM[tile_index] | ((attr & 0x03) << 8);
  159.     SET_TILE_INFO(1,code,((attr & 0x60) >> 3) | ((attr & 0x0c) >> 2));    /* seems correct */
  160. }
  161.  
  162. static void ninjemak_get_tx_tile_info(int tile_index)
  163. {
  164.     int attr = colorram[tile_index];
  165.     int code = videoram[tile_index] | ((attr & 0x03) << 8);
  166.     SET_TILE_INFO(0,code,(attr & 0x1c) >> 2);    /* seems correct ? */
  167. }
  168.  
  169.  
  170.  
  171. /***************************************************************************
  172.  
  173.   Start the video hardware emulation.
  174.  
  175. ***************************************************************************/
  176.  
  177. int galivan_vh_start(void)
  178. {
  179.     bg_tilemap = tilemap_create(get_bg_tile_info,tilemap_scan_rows,TILEMAP_OPAQUE,   16,16,128,128);
  180.     tx_tilemap = tilemap_create(get_tx_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,32,32);
  181.  
  182.     if (!bg_tilemap || !tx_tilemap)
  183.         return 1;
  184.  
  185.     tx_tilemap->transparent_pen = 15;
  186.  
  187.     return 0;
  188. }
  189.  
  190. int ninjemak_vh_start(void)
  191. {
  192.     bg_tilemap = tilemap_create(ninjemak_get_bg_tile_info,tilemap_scan_cols,TILEMAP_OPAQUE,   16,16,512,32);
  193.     tx_tilemap = tilemap_create(ninjemak_get_tx_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,32,32);
  194.  
  195.     if (!bg_tilemap || !tx_tilemap)
  196.         return 1;
  197.  
  198.     tx_tilemap->transparent_pen = 15;
  199.  
  200.     return 0;
  201. }
  202.  
  203.  
  204.  
  205. /***************************************************************************
  206.  
  207.   Memory handlers
  208.  
  209. ***************************************************************************/
  210.  
  211. WRITE_HANDLER( galivan_videoram_w )
  212. {
  213.     if (videoram[offset] != data)
  214.     {
  215.         videoram[offset] = data;
  216.         tilemap_mark_tile_dirty(tx_tilemap,offset);
  217.     }
  218. }
  219.  
  220. WRITE_HANDLER( galivan_colorram_w )
  221. {
  222.     if (colorram[offset] != data)
  223.     {
  224.         colorram[offset] = data;
  225.         tilemap_mark_tile_dirty(tx_tilemap,offset);
  226.     }
  227. }
  228.  
  229. /* Written through port 40 */
  230. WRITE_HANDLER( galivan_gfxbank_w )
  231. {
  232.     /* bits 0 and 1 coin counters */
  233.     coin_counter_w(0,data & 1);
  234.     coin_counter_w(1,data & 2);
  235.  
  236.     /* bit 2 flip screen */
  237.     flipscreen = data & 0x04;
  238.     tilemap_set_flip (bg_tilemap, flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
  239.     tilemap_set_flip (tx_tilemap, flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
  240.  
  241.     /* bit 7 selects one of two ROM banks for c000-dfff */
  242.     {
  243.         int bank = (data & 0x80) >> 7;
  244.         unsigned char *RAM = memory_region(REGION_CPU1);
  245.  
  246.         cpu_setbank(1,&RAM[0x10000 + 0x2000 * bank]);
  247.     }
  248.  
  249. /*    logerror("Address: %04X - port 40 = %02x\n",cpu_get_pc(),data); */
  250. }
  251.  
  252. WRITE_HANDLER( ninjemak_gfxbank_w )
  253. {
  254.     /* bits 0 and 1 coin counters */
  255.     coin_counter_w(0,data & 1);
  256.     coin_counter_w(1,data & 2);
  257.  
  258.     /* bit 2 flip screen */
  259.     flipscreen = data & 0x04;
  260.     tilemap_set_flip (bg_tilemap, flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
  261.     tilemap_set_flip (tx_tilemap, flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
  262.  
  263.     /* bit 3 text bank flag ??? */
  264.     if (data & 0x08)
  265.     {
  266.         /* This is a temporary condition specification. */
  267.  
  268.         int offs;
  269.  
  270. logerror("%04x: write %02x to port 80\n",cpu_get_pc(),data);
  271.  
  272.         for (offs = 0; offs < videoram_size; offs++)
  273.         {
  274.             galivan_videoram_w(offs, 0x20);
  275.         }
  276.         for (offs = 0; offs < videoram_size; offs++)
  277.         {
  278.             galivan_colorram_w(offs, 0x03);
  279.         }
  280.     }
  281.  
  282.     /* bit 4 background disable flag */
  283.     ninjemak_dispdisable = data & 0x10;
  284.  
  285.     /* bit 5 sprite flag ??? */
  286.  
  287.     /* bit 6, 7 ROM bank select */
  288.     {
  289.         int bank = (data & 0xc0) >> 6;
  290.         unsigned char *RAM = memory_region(REGION_CPU1);
  291.  
  292.         cpu_setbank(1,&RAM[0x10000 + 0x2000 * bank]);
  293.     }
  294.  
  295. #if 0
  296.     {
  297.         char mess[80];
  298.         int btz[8];
  299.         int offs;
  300.  
  301.         for (offs = 0; offs < 8; offs++) btz[offs] = (((data >> offs) & 0x01) ? 1 : 0);
  302.  
  303.         sprintf(mess, "BK:%01X%01X S:%01X B:%01X T:%01X FF:%01X C2:%01X C1:%01X", btz[7], btz[6], btz[5], btz[4], btz[3], btz[2], btz[1], btz[0]);
  304.         usrintf_showmessage(mess);
  305.     }
  306. #endif
  307. }
  308.  
  309.  
  310.  
  311. /* Written through port 41-42 */
  312. WRITE_HANDLER( galivan_scrollx_w )
  313. {
  314.     static int up = 0;
  315.     if (offset == 1) {
  316.         if (data & 0x80)
  317.             up = 1;
  318.         else if (up) {
  319.             layers = data & 0x60;
  320.             up = 0;
  321.         }
  322.     }
  323.     scrollx[offset] = data;
  324. }
  325.  
  326. /* Written through port 43-44 */
  327. WRITE_HANDLER( galivan_scrolly_w )
  328. {
  329.     scrolly[offset] = data;
  330. }
  331.  
  332.  
  333. WRITE_HANDLER( ninjemak_scrollx_w )
  334. {
  335.     scrollx[offset] = data;
  336. }
  337.  
  338. WRITE_HANDLER( ninjemak_scrolly_w )
  339. {
  340.     scrolly[offset] = data;
  341. }
  342.  
  343.  
  344.  
  345. /***************************************************************************
  346.  
  347.   Display refresh
  348.  
  349. ***************************************************************************/
  350.  
  351. static void draw_sprites(struct osd_bitmap *bitmap)
  352. {
  353.     int offs;
  354.  
  355.     /* draw the sprites */
  356.     for (offs = 0;offs < spriteram_size;offs += 4)
  357.     {
  358.         int code;
  359.         int attr = spriteram[offs+2];
  360.         int color = (attr & 0x3c) >> 2;
  361.         int flipx = attr & 0x40;
  362.         int flipy = attr & 0x80;
  363.         int sx,sy;
  364.  
  365.         sx = (spriteram[offs+3] - 0x80) + 256 * (attr & 0x01);
  366.         sy = 240 - spriteram[offs];
  367.         if (flipscreen)
  368.         {
  369.             sx = 240 - sx;
  370.             sy = 240 - sy;
  371.             flipx = !flipx;
  372.             flipy = !flipy;
  373.         }
  374.  
  375. //        code = spriteram[offs+1] + ((attr & 0x02) << 7);
  376.         code = spriteram[offs+1] + ((attr & 0x06) << 7);    // for ninjemak, not sure ?
  377.  
  378.         drawgfx(bitmap,Machine->gfx[2],
  379.                 code,
  380.                 color + 16 * (spritepalettebank[code >> 2] & 0x0f),
  381.                 flipx,flipy,
  382.                 sx,sy,
  383.                 &Machine->drv->visible_area,TRANSPARENCY_PEN,15);
  384.     }
  385. }
  386.  
  387.  
  388. void galivan_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  389. {
  390.     tilemap_set_scrollx(bg_tilemap,0,scrollx[0] + 256 * (scrollx[1] & 0x07));
  391.     tilemap_set_scrolly(bg_tilemap,0,scrolly[0] + 256 * (scrolly[1] & 0x07));
  392.  
  393.     tilemap_update (ALL_TILEMAPS);
  394.     tilemap_render (ALL_TILEMAPS);
  395.  
  396.     if (layers & 0x40)
  397.         fillbitmap(bitmap,Machine->pens[0],&Machine->drv->visible_area);
  398.     else
  399.         tilemap_draw(bitmap,bg_tilemap,0);
  400.  
  401.     tilemap_draw (bitmap,tx_tilemap,0);
  402.  
  403.     draw_sprites(bitmap);
  404.  
  405.     tilemap_draw (bitmap,tx_tilemap,1);
  406. }
  407.  
  408. void ninjemak_vh_screenrefresh(struct osd_bitmap *bitmap, int full_refresh)
  409. {
  410.     /* (scrollx[1] & 0x40) does something */
  411.     tilemap_set_scrollx(bg_tilemap,0,scrollx[0] + 256 * (scrollx[1] & 0x1f));
  412.     tilemap_set_scrolly(bg_tilemap,0,scrolly[0] + 256 * (scrolly[1] & 0xff));
  413.  
  414.     tilemap_update(ALL_TILEMAPS);
  415.     tilemap_render(ALL_TILEMAPS);
  416.  
  417.     if (ninjemak_dispdisable)
  418.         fillbitmap(bitmap,Machine->pens[0],&Machine->drv->visible_area);
  419.     else
  420.         tilemap_draw(bitmap,bg_tilemap,0);
  421.  
  422.     draw_sprites(bitmap);
  423.  
  424.     tilemap_draw(bitmap,tx_tilemap,0);
  425. }
  426.